package com.gugu.procedure.service;

import com.alibaba.druid.support.json.JSONUtils;
import com.gugu.procedure.bean.*;
import com.gugu.procedure.common.Constant;
import com.gugu.procedure.common.MessageResult;
import com.gugu.procedure.dao.*;
import com.gugu.procedure.exceptions.BusinessException;
import com.gugu.procedure.util.BeanUtil;
import com.gugu.procedure.util.DateUtil;
import com.gugu.procedure.util.MapUtil;
import com.gugu.procedure.util.StringUtil;
import com.gugu.procedure.vo.ReplenishmentVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class ReplenishmentService {

    @Autowired
    private ReplenishmentDao replenishmentDao;
    @Autowired
    private ProductionDao productionDao;
    @Autowired
    private ProductionRecordDao productionRecordDao;
    @Autowired
    private OrderProductionRecordDao orderProductionRecordDao;
    @Autowired
    private ProductionRecordService productionRecordService;
    @Autowired
    private OrderItemDao orderItemDao;
    @Autowired
    private InsideOrderDao insideOrderDao;


    /**
     * 批量补料申请查询
     * 扫描新品产品码 获得订单号和模具编号
     * 选择当前产品的工艺
     * 根据订单号和模具编号查询其对应的规格
     * 根据订单号、规格、当前工艺查询当前工艺所有规格的模具编码、规格号
     *
     * @param orderNo
     * @param number
     * @param production
     * @return
     */
    public List listReplenishment(String orderNo, String number, String production) {
        OrderItem orderItem = orderItemDao.queryByOrderNoAndNumberForUpdate(orderNo, number);
        String specs = orderItem.getSpecs();
        List<ProductionRecord> list = productionRecordDao.findAllByOrderNoAndSpecsAndProductionAndStatusAndIsDelOrderByNumber(orderNo, specs, production, "1", "0");
        return list;
    }

    public MessageResult save(Replenishment replenishment) {
        replenishmentDao.save(replenishment);
        return MessageResult.success();
    }

    public MessageResult page(String role, String status, String orderNo, String month, String staffName, int pageNo, int pageSize) {

        // 查询规则：如果是品管角色 ，则查询责任部门为材质的
        // 如果是仓库 则查询责任部门为非材质的
        // 如果是管理员 则查询全部
        // 如果是其他 则返回空
//        Specification<Replenishment> spec = (Specification<Replenishment>) (root, query, cb) -> {
//            List<Predicate> list = new ArrayList<>();
//            if (StringUtils.hasText(orderNo)) {
//                list.add(cb.equal(root.get("orderNo").as(String.class), orderNo));
//            }
//            if (StringUtils.hasText(role)) {
//                if (role.equals(Constant.MANAGER_QC)) {
//                    list.add(cb.equal(root.get("dept").as(String.class), Constant.RESPONSIBLE_DEPARTMENT));
//                } else if (role.equals(Constant.MANAGER_WAREHOUSE)) {
//                    list.add(cb.notEqual(root.get("dept").as(String.class), Constant.RESPONSIBLE_DEPARTMENT));
//                } else {
//                    // 需要返回空 则添加一个不成立的条件
//                    list.add(cb.equal(root.get("dept").as(String.class), "NO"));
//                }
//            }
//            if (StringUtils.hasText(staffName)) {
//                list.add(cb.like(root.get("staffName").as(String.class), "%" + staffName + "%"));
//            }
//            if (StringUtils.hasText(status)) {
//                list.add(cb.equal(root.get("status").as(String.class), status));
//            }
//            Predicate[] pre = new Predicate[list.size()];
//            query.where(list.toArray(pre));
//            return query.getRestriction();
//        };
//        PageRequest pr = PageRequest.of(pageNo - 1, pageSize, Sort.Direction.DESC, "createTime");
//        Page<Replenishment> recordsPage = replenishmentDao.findAll(spec, pr);

        List<String> depts = new ArrayList<>();
        if (StringUtil.isNotEmpty(role)) {
            depts = new ArrayList<>();
            //  如果是品管  则查询责任不为才材质的
            if (role.equals(Constant.MANAGER_TECHNOLOGY)) {
                depts.add(Constant.MANAGER_TECHNOLOGY);
            } else if (role.equals(Constant.MANAGER_QC)) {
                depts.add(Constant.RESPONSIBLE_DEPARTMENT);
            }
            //  如果是仓库 则查询所有的记录
            else if (role.equals(Constant.MANAGER_WAREHOUSE)) {
                depts.add(Constant.MANAGER_PRODUCTION);
                depts.add(Constant.MANAGER_QC);
                depts.add(Constant.MANAGER_TECHNOLOGY);
                depts.add(Constant.MANAGER_PLAIN);
                depts.add(Constant.MANAGER_BUSINESS);
            } else {
                depts.add("NO");

            }
        } else {
            depts.add(Constant.RESPONSIBLE_DEPARTMENT);
            depts.add(Constant.MANAGER_PRODUCTION);
            depts.add(Constant.MANAGER_QC);
            depts.add(Constant.MANAGER_TECHNOLOGY);
            depts.add(Constant.MANAGER_PLAIN);
            depts.add(Constant.MANAGER_BUSINESS);
        }

        //
        long count = 0;
        List<Map<String, Object>> list = new ArrayList<>();
        if (StringUtil.isEmpty(role)) {
            count = replenishmentDao.countAdmin(depts, status, month, orderNo, staffName);
            list = replenishmentDao.pageAdmin(depts, status, month, orderNo, staffName, (pageNo - 1) * pageSize, pageSize);
        } else if (Constant.MANAGER_QC.equals(role)) {
            count = replenishmentDao.countQc(depts, status, month, orderNo, staffName);
            list = replenishmentDao.pageQc(depts, status, month, orderNo, staffName, (pageNo - 1) * pageSize, pageSize);
        } else if (role.equals(Constant.MANAGER_WAREHOUSE)) {
            count = replenishmentDao.countWarehouse(status, month, orderNo, staffName);
            list = replenishmentDao.pageWarehouse(status, month, orderNo, staffName, (pageNo - 1) * pageSize, pageSize);
        } else if (role.equals(Constant.MANAGER_TECHNOLOGY)) {
            count = replenishmentDao.countTechnology(status, month, orderNo, staffName);
            list = replenishmentDao.pageTechnology(status, month, orderNo, staffName, (pageNo - 1) * pageSize, pageSize);
        }

        List<ReplenishmentVo> voList = new ArrayList<>();
        for (Map<String, Object> map : list) {
            ReplenishmentVo vo = new ReplenishmentVo();
            vo = (ReplenishmentVo) MapUtil.map2Bean(map, vo);
            if ("0".equals(vo.getStatus())) {
                vo.setStatus("待审核");
                if (vo.getCheckTime() != null) {
                    vo.setStatus("待仓库审核");
                }
            } else if ("1".equals(vo.getStatus())) {
                vo.setStatus("通过");
            } else if ("2".equals(vo.getStatus())) {
                vo.setStatus("拒绝");
            }
            voList.add(vo);
        }

        MessageResult mr = MessageResult.success();
        mr.setTotal(count);
        mr.setTotalElement(voList);
        return mr;
    }


    /**
     * 审核通过
     *
     * @param checkPerson
     * @param checkPersonName
     * @param id
     * @param production
     * @param remark
     * @return
     */
    @Transactional
    public MessageResult checkPass(String role, String checkPerson, String checkPersonName, Long id, String production, String remark) {
        // 审核通过  修改该审核订单的状态
        // 修改产品的流转状态 将该产品的工艺定位到指定工艺的上一个工艺的结束状态
        // 如果是激光原因  就是先技术 然后仓库
        // 如果是材质 就是先品管 然后仓库
        // 其他就是直接仓库
        Replenishment replenishment = replenishmentDao.findById(id).get();
        //  如果是品管审核
        if (Constant.MANAGER_QC.equals(role)) {
            replenishment.setCheckTime(DateUtil.getFormatedDateTime());
            replenishment.setCheckPerson(checkPerson);
            replenishment.setResetProduction(production);
            replenishment.setCheckPersonName(checkPersonName);
            replenishment.setRemark(remark);
            replenishmentDao.save(replenishment);
            return MessageResult.success();
        } else if (Constant.MANAGER_TECHNOLOGY.equals(role)) {
            replenishment.setCheckTime(DateUtil.getFormatedDateTime());
            replenishment.setCheckPerson(checkPerson);
            replenishment.setResetProduction(production);
            replenishment.setCheckPersonName(checkPersonName);
            replenishment.setRemark(remark);
            replenishmentDao.save(replenishment);
            return MessageResult.success();
        } else {
            replenishment.setStatus(Constant.STATUS_1);
            replenishment.setCheckTime(DateUtil.getFormatedDateTime());
            replenishment.setCheckPerson(checkPerson);
            replenishment.setResetProduction(production);
            replenishment.setCheckPersonName(checkPersonName);
            replenishment.setRemark(remark);
            replenishmentDao.save(replenishment);
        }
        String orderNo = replenishment.getOrderNo();
        String number = replenishment.getNumber();
        String specs = replenishment.getSpecs();
        Production productions = productionDao.findTopByOrderNoAndSpecs(orderNo, specs);
        if (Objects.isNull(production) || Objects.isNull(productions.getProcedures())) {
            throw new BusinessException("请检查该订单参数表是否已上传");
        }
        List<String> list = (List) JSONUtils.parse(productions.getProcedures());
        // 增加校验  重置的工序只能是提交申请工序之前
        boolean productionCheck = false;
//        for (String s : list) {
//            // 说明重置工序是故障工序之前
//            if (s.equals(replenishment.getResetProduction())) {
//                productionCheck = true;
//            }
//            if (s.equals(replenishment.getProduction())) {
//                if (s.equals(replenishment.getResetProduction())) {
//                    productionCheck = true;
//                }
//                break;
//            }
//        }
        // 过滤处哪些是需要设置为3的 哪些是需要设置系统为1 的
        List<String> adds = new ArrayList<>();
        List<String> adds3 = new ArrayList<>();
        if (!productionCheck) {
            boolean addFlag = false;
            boolean currentFlag = false;
            boolean resetFlag = false;
            int currentIndex = 0;
            int resetIndex = 0;
            for (int k = 0; k < list.size(); k++) {
                String s = list.get(k);
                if (s.equals(replenishment.getProduction())) {
                    currentIndex = k;
                }
                if (s.equals(replenishment.getResetProduction())) {
                    resetIndex = k;
                }
            }
            //循环出哪些工序被过滤掉了 从补料申请的工序（包含）到重置的工序（不包含）
            for (int k = 0; k < list.size(); k++) {
                String s = list.get(k);
                if (s.equals(replenishment.getProduction())) {
                    addFlag = true;
                    currentFlag = true;
                    currentIndex = k;
                }
                if (s.equals(replenishment.getResetProduction())) {
                    addFlag = true;
                    resetFlag = true;
                    resetIndex = k;
                }
                // 重置工艺在当前工艺之后 则需要添加系统完成的工艺
                if (addFlag && currentIndex < resetIndex && k < resetIndex) {
                    adds.add(s);
                }
                // 重置工艺在当前工艺之前  则需要作废后面的工艺
                if (addFlag && currentIndex >= resetIndex) {
                    adds3.add(s);
                }
                if (currentFlag && resetFlag) {
                    break;
                }
            }
        }
        if (!adds3.contains(replenishment.getProduction())) {
            adds3.add(replenishment.getProduction());
        }
        boolean updateFlag = false;
        long longTime = System.currentTimeMillis();

        for (int i = 0; i < adds3.size(); i++) {
            // 需要将该工艺即后面的工艺记录状态更新为补料作废
            ProductionRecord productionRecord = productionRecordDao.findTopByOrderNoAndNumberAndProductionOrderByIdDesc(orderNo, number, adds3.get(i));
            if (Objects.nonNull(productionRecord)) {
                productionRecord.setRemark("补料通过作废,补料编号：" + replenishment.getId());
                productionRecord.setStatus(Constant.PRODUCTION_RECORD_3);
                productionRecordDao.save(productionRecord);
            }
            // 处理 OrderProductionRecord
            OrderProductionRecord orderProductionRecord = orderProductionRecordDao.findTopByOrderNoAndProductionAndStatus(orderNo, adds3.get(i), Constant.STATUS_1);
            if (Objects.nonNull(orderProductionRecord)) {
                orderProductionRecord.setStatus(Constant.STATUS_0);
                orderProductionRecord.setUpdateTime(DateUtil.getFormatedDateTime());
                orderProductionRecordDao.save(orderProductionRecord);
            }
        }
        // 中间跳转工序系统自动填充
        String time = DateUtil.getFormatedDateTime();
        String createTime = DateUtil.formatDate(new Date(longTime), DateUtil.DATE_TIME_FORMAT);
        longTime = longTime + 1000;
        ProductionRecord productionRecord = new ProductionRecord();
        productionRecord.setWorkDoneFlag(Constant.WORK_DONE_FLAG_N);
        productionRecord.setNgTag("0");
        productionRecord.setStaffName(Constant.SYSTEM_STAFF_NAME);
        productionRecord.setStaffId(Constant.SYSTEM_STAFF_ID);
        productionRecord.setStaffNumber(Constant.SYSTEM_STAFF_NUMBER);
        productionRecord.setStatus(Constant.STATUS_1);
        productionRecord.setStartTime(time);
        productionRecord.setCreateTime(createTime);
        productionRecord.setEndTime(time);
        Production p = productionDao.findTopByOrderNoAndSpecs(replenishment.getOrderNo(), replenishment.getSpecs());
        productionRecord.setProductionId(p.getId());
        productionRecord.setNumber(replenishment.getNumber());
        productionRecord.setSpecs(replenishment.getSpecs());
        productionRecord.setOrderNo(replenishment.getOrderNo());

        List<OrderProductionRecord> orderProductionRecords = new ArrayList<>();
        List<ProductionRecord> productionRecords = new ArrayList<>();
        for (int i = 0; i < adds.size(); i++) {

            ProductionRecord bean = new ProductionRecord();
            BeanUtil.copyProperties(productionRecord, bean);
            bean.setProduction(adds.get(i));
            productionRecords.add(bean);

            OrderProductionRecord orderProductionRecord = new OrderProductionRecord();
            orderProductionRecord.setStatus(Constant.STATUS_1);
            orderProductionRecord.setOrderNo(replenishment.getOrderNo());
            orderProductionRecord.setProduction(adds.get(i));
            orderProductionRecord.setStartTime(time);
            orderProductionRecord.setEndTime(time);
            orderProductionRecords.add(orderProductionRecord);
        }
        if (adds.size() > 0) {
            orderProductionRecordDao.saveAll(orderProductionRecords);
            productionRecordDao.saveAll(productionRecords);

            // 将提交申请时的工艺记录设置为作废
//            ProductionRecord temp = productionRecordDao.findTopByOrderNoAndNumberAndProductionOrderByIdDesc(orderNo, number, adds.get(0));
//            if (Objects.nonNull(productionRecord)) {
//                productionRecord.setRemark("补料通过作废,补料编号：" + replenishment.getId());
//                productionRecord.setStatus(Constant.PRODUCTION_RECORD_3);
//                productionRecordDao.save(productionRecord);
//            }
        }


        return MessageResult.success();
    }

    @Transactional
    public MessageResult checkRefuse(String checkPerson, String checkPersonName, Long id, String remark) {
        // 审核通过  修改该审核订单的状态
        // 修改产品的流转状态 将该产品的工艺定位到指定工艺的上一个工艺的结束状态
        Replenishment replenishment = replenishmentDao.findById(id).get();
        replenishment.setStatus(Constant.REPLENISHMENT_REFUSE);
        replenishment.setCheckTime(DateUtil.getFormatedDateTime());
        replenishment.setCheckPerson(checkPerson);
        replenishment.setCheckPersonName(checkPersonName);
        replenishment.setRemark(remark);
        replenishmentDao.save(replenishment);

        // 找到补料申请的记录 将其状态还原成正常状态
        ProductionRecord bean = productionRecordDao.
                findTopByOrderNoAndNumberAndStatusOrderByIdDesc(replenishment.getOrderNo(), replenishment.getNumber(),
                        Constant.PRODUCTION_RECORD_2);
        if (Objects.nonNull(bean)) {
            bean.setStatus(Constant.PRODUCTION_RECORD_1);
            bean.setRemark("补料申请拒绝，状态返回");
            productionRecordDao.save(bean);
        }
        return MessageResult.success();
    }


    public Map<String, Object> queryReplenishmentParams(String orderNo, String specs) {
        Map<String, Object> map = orderItemDao.queryReplenishmentParams(orderNo, specs);
        InsideOrder insideOrder = insideOrderDao.findTopByOrderNo(cn.hutool.core.map.MapUtil.getStr(map, "order_no"));
        Map<String, Object> newMap = new HashMap<>(map);
        if (insideOrder != null) {
            newMap.put("customer", insideOrder.getCustomer());
            newMap.put("custOrderNo", insideOrder.getCustOrderNo());
        }
        return newMap;
    }

}
